﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Web7.Dispose;
using System.Web;
using Web7.Ioc;
using System.Web.Mvc;
using Web7.Core.Context;
using System.Web.Routing;

namespace Web7.Core.BootStrapperTask
{
    /// <summary>
    /// 应用程序启动管理
    /// </summary>
    public class BootManager : DisposableObject
    {
        private readonly HttpApplication _app;
        private readonly DisposableTimer _timer;
        private readonly Web7ContainerBuilder<HttpApplication> _web7Wireup; //创建一些模块，注入IOC
        private Func<AbstractContainerBuilder> _containerDelegate;
        private Type _dependencyResolverType;
        private Func<IWeb7DependencyResolver, IDependencyResolver> _mvcResolverFactory;
        //private ApplicationTaskManager _taskManager;

        /// <summary>
        /// 应用程序启动管理
        /// </summary>
        /// <param name="app"></param>
        public BootManager(HttpApplication app)
        {
            _timer = DisposableTimer.Start(timer => { }); //LogHelper.TraceIfEnabled<BootManager>("Application start took {0}ms", () => timer)

            _app = app;
            //LogHelper.TraceIfEnabled<BootManager>("Created");

            _web7Wireup = new Web7ContainerBuilder<HttpApplication>(_app);
        }

        /// <summary>
        /// 实例化依赖管理容器
        /// </summary>
        /// <param name="container">登记服务与特定的依赖管理容器.</param>
        /// <returns></returns>
        public BootManager InitializeContainer(Func<AbstractContainerBuilder> container)
        {
            //LogHelper.TraceIfEnabled<BootManager>("Initialising container");
            _containerDelegate = container;
            return this;
        }

        /// <summary>
        /// 设置Mvc的依赖容器姐方案
        /// </summary>
        /// <param name="mvcResolverFactory">回调函数</param>
        /// <returns></returns>
        public BootManager SetMvcResolverFactory(Func<IWeb7DependencyResolver,IDependencyResolver> mvcResolverFactory)
        {
            _mvcResolverFactory = mvcResolverFactory;
            return this;
        }

        /// <summary>
        /// 注册依赖容器管理准备启动事件
        /// </summary>
        /// <param name="handler"></param>
        /// <returns></returns>
        public BootManager AddContainerBuildingHandler(EventHandler<ContainerBuilderEventArgs> handler)
        {
            _web7Wireup.ContainerBuilding += handler;
            return this;
        }

        /// <summary>
        /// 注册依赖容器管理启动成功事件
        /// </summary>
        /// <param name="handler"></param>
        /// <returns></returns>
        public BootManager AddContainerBuildingCompleteHandler(EventHandler<ContainerBuilderEventArgs> handler)
        {
            _web7Wireup.ContainerBuildingComplete += handler;
            return this;
        }

        /// <summary>
        /// 注册错误处理事件
        /// </summary>
        /// <param name="handler"></param>
        /// <returns></returns>
        public BootManager AddAppErrorHandler(EventHandler handler)
        {
            _app.Error += handler;
            return this;
        }

        /// <summary>
        ///  Wires everything up
        /// </summary>
        /// <returns></returns>
        public virtual IWeb7ApplicationContext Boot()
        {
            
            //LogHelper.TraceIfEnabled<BootManager>("Booting");
            var container = _containerDelegate();
            
            container.AddDependencyDemandBuilder(_web7Wireup);

            var built = container.Build();
            
            var mvcResolver = _mvcResolverFactory.Invoke(built);
            DependencyResolver.SetResolver(mvcResolver);

            //_taskManager = built.Resolve<ApplicationTaskManager>();

            //launch pre-app startup tasks
            //_taskManager.ExecuteInContext(TaskTriggers.PreAppStartupComplete, new TaskExecutionContext(this, null));

            // Initialise the Umbraco system (v2)
            // If this is a Cms app:
            //LogHelper.TraceIfEnabled<BootManager>("Booting CmsBootstrapper");
            //built.Resolve<CmsBootstrapper>().Boot(RouteTable.Routes);

            // If this is a front-end app:
            //LogHelper.TraceIfEnabled<BootManager>("Booting RenderBootstrapper");
            //built.Resolve<RenderBootstrapper>().Boot(RouteTable.Routes);

            //launch post app startup tasks
            //_taskManager.ExecuteInContext(TaskTriggers.PostAppStartup, new TaskExecutionContext(this, null));
            
            return built.Resolve<IWeb7ApplicationContext>();
        }

        protected override void DisposeResources()
        {
            _timer.Dispose();
        }

    }
}
